﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.SystemUI;
using PlanningGIS.Framework;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Carto;

using ESRI.ArcGIS.Controls;
using System.Runtime.InteropServices;
using DevComponents.DotNetBar;
using PlanningGIS.Win.Controls;

namespace PlanningGIS.Tools
{
    /// <summary>
    /// 自定义比例尺控件
    /// </summary>
    public partial class MapZoomToolControl : UserControl, ESRI.ArcGIS.SystemUI.ICommand
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public MapZoomToolControl()
        {
            InitializeComponent();
            if (!this.DesignMode)
            {
                if (AppConfig.SystemConfig == null) return;
                List<string> scales = new List<string>();
                if (AppConfig.SystemConfig == null || string.IsNullOrEmpty(AppConfig.SystemConfig.基本信息.默认比例尺))
                {
                    scales.Add("1:500");
                    scales.Add("1:2000");
                    scales.Add("1:10000");
                    scales.Add("1:50000");
                    scales.Add("1:250000");
                    scales.Add("1:1000000");
                }
                else
                {
                    string[] sc = AppConfig.SystemConfig.基本信息.默认比例尺.Split(';');
                    foreach (string itm in sc)
                    {
                        scales.Add(itm);
                    }
                }
                SetScale(scales);
                cmbScale.KeyPress += ControlVerify.txtDoubleBox_KeyPress;
            }
            
        }

        /// <summary>
        /// 
        /// </summary>
        IApplication m_Application = null;
        /// <summary>
        /// 是否锁定比例尺
        /// </summary>
        private bool _IsLock = false;
        /// <summary>
        /// 
        /// </summary>
        private bool _IsLockChange = false;
        /// <summary>
        /// 
        /// </summary>
        private double _OldSacle = -1;

        #region ICommand Members
        /// <summary>
        /// 
        /// </summary>
        int ESRI.ArcGIS.SystemUI.ICommand.Bitmap
        {
            get { return 0; }
        }
        /// <summary>
        /// 
        /// </summary>
        string ESRI.ArcGIS.SystemUI.ICommand.Caption
        {
            get { return "MapZoomToolControl"; }
        }
        /// <summary>
        /// 
        /// </summary>
        string ESRI.ArcGIS.SystemUI.ICommand.Category
        {
            get { return "比例尺"; }
        }
        /// <summary>
        /// 
        /// </summary>
        bool ESRI.ArcGIS.SystemUI.ICommand.Checked
        {
            get { return false; }
        }
        /// <summary>
        /// 
        /// </summary>
        bool ESRI.ArcGIS.SystemUI.ICommand.Enabled
        {
            get
            {
                if (m_Application == null) return false;
                if ((m_Application as IFramework).IsSceneCtlActive) return false;
                if ((m_Application as IFramework).IsMapCtrlactive)
                {
                    if ((m_Application as IFramework).MapControl.MapUnits == ESRI.ArcGIS.esriSystem.esriUnits.esriUnknownUnits)
                        return false;
                    //if ((m_Application as IFramework).MapControl.SpatialReference == null || (m_Application as IFramework).MapControl.SpatialReference is ESRI.ArcGIS.Geometry.IUnknownCoordinateSystem)
                    //{
                    //    cmbScale.Text = "";
                    //    return false;
                    //}
                    //else 
                    return true;
                }
                else
                {
                    if ((m_Application as IFramework).PageLayoutControl.ActiveView.FocusMap.MapUnits == ESRI.ArcGIS.esriSystem.esriUnits.esriUnknownUnits ||
                        (m_Application as IFramework).PageLayoutControl.ActiveView.FocusMap.SpatialReference == null || 
                        (m_Application as IFramework).PageLayoutControl.ActiveView.FocusMap.SpatialReference is ESRI.ArcGIS.Geometry.IUnknownCoordinateSystem)
                    {

                        cmbScale.Text = "";
                        return false;
                    }
                    else return true;
                }

            }
        }
        /// <summary>
        /// 
        /// </summary>
        int ESRI.ArcGIS.SystemUI.ICommand.HelpContextID
        {
            get { return 0; }
        }
        /// <summary>
        /// 
        /// </summary>
        string ESRI.ArcGIS.SystemUI.ICommand.HelpFile
        {
            get { return string.Empty; }
        }
        /// <summary>
        /// 
        /// </summary>
        string ESRI.ArcGIS.SystemUI.ICommand.Message
        {
            get { return "比例尺"; }
        }
        /// <summary>
        /// 
        /// </summary>
        string ESRI.ArcGIS.SystemUI.ICommand.Name
        {
            get { return "MapZoomToolControl"; }
        }
        /// <summary>
        /// 
        /// </summary>
        void ESRI.ArcGIS.SystemUI.ICommand.OnClick()
        {
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="hook"></param>
        void ESRI.ArcGIS.SystemUI.ICommand.OnCreate(object hook)
        {

            if (m_Application == null)
            {
                m_Application = hook as IApplication;
                IMap pMap;
                if ((m_Application as IFramework).IsMapCtrlactive)
                {
                    IMapControlEvents2_Event mapEvent = (m_Application as IFramework).MapControl as IMapControlEvents2_Event;
                    mapEvent.OnExtentUpdated -= new IMapControlEvents2_OnExtentUpdatedEventHandler(mapEvent_OnExtentUpdated);
                    mapEvent.OnExtentUpdated += new IMapControlEvents2_OnExtentUpdatedEventHandler(mapEvent_OnExtentUpdated);

                    mapEvent.OnViewRefreshed -= new IMapControlEvents2_OnViewRefreshedEventHandler(mapEvent_OnViewRefreshed);
                    mapEvent.OnViewRefreshed += new IMapControlEvents2_OnViewRefreshedEventHandler(mapEvent_OnViewRefreshed);
                    pMap = (m_Application as IFramework).MapControl.Map;
                }
                else
                {
                    IPageLayoutControlEvents_Event pageEvent = (m_Application as IFramework).PageLayoutControl as IPageLayoutControlEvents_Event;
                    pageEvent.OnExtentUpdated -= new IPageLayoutControlEvents_OnExtentUpdatedEventHandler(pageEvent_OnExtentUpdated);
                    pageEvent.OnExtentUpdated += new IPageLayoutControlEvents_OnExtentUpdatedEventHandler(pageEvent_OnExtentUpdated);

                    pMap = (m_Application as IFramework).PageLayoutControl.ActiveView.FocusMap;
                }
                (m_Application as IFramework).OnMapPageSwitchEvent -= new OnMapPageSwitchEventHandler(DropDownMapScale_OnMapPageSwitchEvent);
                (m_Application as IFramework).OnMapPageSwitchEvent += new OnMapPageSwitchEventHandler(DropDownMapScale_OnMapPageSwitchEvent);
            }
        }

        void mapEvent_OnViewRefreshed(object ActiveView, int viewDrawPhase, object layerOrElement, object envelope)
        {
            if ((m_Application as IFramework).IsMapCtrlactive)
            {
                if ((m_Application as IFramework).MapControl.MapUnits == ESRI.ArcGIS.esriSystem.esriUnits.esriUnknownUnits)
                    return;
                cmbScale.Text = "1:" + Math.Round((m_Application as IFramework).MapControl.MapScale, 3);
            }
            else
            {
                if ((m_Application as IFramework).PageLayoutControl.ActiveView.FocusMap.MapUnits == ESRI.ArcGIS.esriSystem.esriUnits.esriUnknownUnits)
                    return;
                double dblScale = (m_Application as IFramework).PageLayoutControl.ActiveView.FocusMap.MapScale;
                long scale = dblScale >= long.MaxValue ? long.MaxValue : (long)dblScale;
                cmbScale.Text = "1:" + scale;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        void DropDownMapScale_OnMapPageSwitchEvent()
        {
            if (this.Enabled == false) return;
            if ((m_Application as IFramework).IsMapCtrlactive)
            {
                if ((m_Application as IFramework).MapControl.MapUnits == ESRI.ArcGIS.esriSystem.esriUnits.esriUnknownUnits)
                    return;
                try
                {
                    
                    cmbScale.Text = "1:" + (int)(m_Application as IFramework).MapControl.ActiveView.FocusMap.MapScale;
                }
                catch (System.Exception)
                {
                }
            }
            else
            {
                if ((m_Application as IFramework).PageLayoutControl.ActiveView.FocusMap.MapUnits == ESRI.ArcGIS.esriSystem.esriUnits.esriUnknownUnits)
                    return;
                try
                {
                    cmbScale.Text = "1:" + (int)(m_Application as IFramework).PageLayoutControl.ActiveView.FocusMap.MapScale;
                }
                catch (System.Exception) { }

            }
        }
        /// <summary>
        /// 
        /// </summary>
        string ESRI.ArcGIS.SystemUI.ICommand.Tooltip
        {
            get { return "比例尺设置"; }
        }

        #endregion
        /// <summary>
        /// 
        /// </summary>
        /// <param name="displayTransformation"></param>
        /// <param name="sizeChanged"></param>
        /// <param name="newEnvelope"></param>
        void pageEvent_OnExtentUpdated(object displayTransformation, bool sizeChanged, object newEnvelope)
        {
            if ((m_Application as IFramework).IsMapCtrlactive)
            {
                if ((m_Application as IFramework).MapControl.MapUnits == ESRI.ArcGIS.esriSystem.esriUnits.esriUnknownUnits)
                    return;
                if ((m_Application as IFramework).MapControl.MapScale > 10000000)
                {
                    (m_Application as IFramework).MapControl.MapScale = 10000000;
                }
                if ((m_Application as IFramework).MapControl.MapScale < 0.001)
                {
                    (m_Application as IFramework).MapControl.MapScale = 0.001;
                }
                double dblScale = (m_Application as IFramework).MapControl.MapScale;
                long scale = dblScale >= long.MaxValue ? long.MaxValue : (long)dblScale;
                cmbScale.Text = "1:" + scale;
            }
            else
            {
                if ((m_Application as IFramework).PageLayoutControl.ActiveView.FocusMap.MapUnits == ESRI.ArcGIS.esriSystem.esriUnits.esriUnknownUnits)
                    return;
                double dblScale = (m_Application as IFramework).PageLayoutControl.ActiveView.FocusMap.MapScale;
                long scale = dblScale >= long.MaxValue ? long.MaxValue : (long)dblScale;
                cmbScale.Text = "1:" + scale;

            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="displayTransformation"></param>
        /// <param name="sizeChanged"></param>
        /// <param name="newEnvelope"></param>
        void mapEvent_OnExtentUpdated(object displayTransformation, bool sizeChanged, object newEnvelope)
        {
            if ((m_Application as IFramework).IsMapCtrlactive)
            {
                if ((m_Application as IFramework).MapControl.MapUnits == ESRI.ArcGIS.esriSystem.esriUnits.esriUnknownUnits)
                    return;
                double newScale = (m_Application as IFramework).MapControl.MapScale;
                if (_IsLock)
                {
                    if (!_IsLockChange)
                    {
                        _IsLockChange = true;
                        if (_OldSacle > newScale)
                        {
                            for (int i = cmbScale.Items.Count-2; i >=0; i--)
                            {                                
                                double si = double.Parse(cmbScale.Items[i].ToString().Split(':')[1]);
                                if (si >= _OldSacle)
                                {
                                    if (i == 0)
                                    {
                                        (m_Application as IFramework).MapControl.MapScale = si;
                                        break;
                                    }
                                    continue;
                                }
                                if (newScale >= si)
                                {
                                    (m_Application as IFramework).MapControl.MapScale = si;
                                    break;
                                }
                                else
                                {
                                    if (i == 0)
                                    {
                                        (m_Application as IFramework).MapControl.MapScale = si;
                                        break;
                                    }
                                }
                            }
                        }
                        else if (_OldSacle < newScale)
                        {
                            for (int i = 0; i < cmbScale.Items.Count-1; i++)
                            {
                                double si = double.Parse(cmbScale.Items[i].ToString().Split(':')[1]);
                                if (_OldSacle >= si)
                                {
                                    if (i == cmbScale.Items.Count - 2)
                                    {
                                        (m_Application as IFramework).MapControl.MapScale = si;
                                        break;
                                    }
                                    continue;
                                }
                                if (newScale <= si)
                                {
                                    (m_Application as IFramework).MapControl.MapScale = si;
                                    break;
                                }
                                else
                                {
                                    if (i == cmbScale.Items.Count - 2)
                                    {
                                        (m_Application as IFramework).MapControl.MapScale = si;
                                        break;
                                    }
                                }
                            }                
                        }                                
                        _IsLockChange = false;
                        _OldSacle = (m_Application as IFramework).MapControl.MapScale;
                    }                    
                }
                else
                {
                    if (newScale > 10000000)
                    {
                        (m_Application as IFramework).MapControl.MapScale = 10000000;
                    }
                    if (newScale < 0.001)
                    {
                        (m_Application as IFramework).MapControl.MapScale = 0.001;
                    }
                    _OldSacle = (m_Application as IFramework).MapControl.MapScale;
                }
                cmbScale.Text = "1:" + Math.Round((m_Application as IFramework).MapControl.MapScale, 3);
            }
            else
            {
                if ((m_Application as IFramework).PageLayoutControl.ActiveView.FocusMap.MapUnits == ESRI.ArcGIS.esriSystem.esriUnits.esriUnknownUnits)
                    return;
                double dblScale = (m_Application as IFramework).PageLayoutControl.ActiveView.FocusMap.MapScale;
                long scale = dblScale >= long.MaxValue ? long.MaxValue : (long)dblScale;
                cmbScale.Text = "1:" + scale;

            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbScale_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData != Keys.Enter) return;
            if (m_Application == null) return;
            IActiveView pActiveView;
            if ((m_Application as IFramework).IsMapCtrlactive)
            {
                pActiveView = (m_Application as IFramework).MapControl.ActiveView;
            }
            else
            {
                pActiveView = (m_Application as IFramework).PageLayoutControl.ActiveView;
            }
            if (cmbScale.Text.Trim() == "")
            {
                cmbScale.Text = "1:" + (int)pActiveView.FocusMap.MapScale;
                return;
            }
            if (cmbScale.Text.Contains(":"))
            {
                string[] strs = cmbScale.Text.Split(":".ToCharArray());
                if (strs.Length != 2)
                {
                    cmbScale.Text = "1:" + (int)pActiveView.FocusMap.MapScale;
                    return;
                }
                if (strs[0].Trim() != "1")
                {
                    cmbScale.Text = "1:" + (int)pActiveView.FocusMap.MapScale;
                    return;
                }
                double dbl;
                if (double.TryParse(strs[1], out dbl))
                {
                    pActiveView.FocusMap.MapScale = dbl;
                    pActiveView.Refresh();


                }
                else
                {
                    cmbScale.Text = "1:" + (int)pActiveView.FocusMap.MapScale;
                }
            }
            else
            {
                double dbl;
                if (double.TryParse(cmbScale.Text.Trim(), out dbl))
                {
                    pActiveView.FocusMap.MapScale = dbl;
                    pActiveView.Refresh();
                }
                else
                {
                    cmbScale.Text = "1:" + (int)pActiveView.FocusMap.MapScale;
                }
            }
        }
        /// <summary>
        /// 选择比例尺
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void cmbScale_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (cmbScale.SelectedItem == null)
                return;
            if (cmbScale.SelectedItem is Control)
            {
                cmbScale.Text = Math.Round((m_Application as IFramework).MapControl.MapScale, 3).ToString();
                SettingScale();
                //Application.DoEvents();
                timer.Enabled = true;
                timer.Start();                
            }
            else
            {
                KeyEventArgs ee = new KeyEventArgs(Keys.Enter);
                cmbScale_KeyDown(null, ee);
            }
        }
        /// <summary>
        /// 设置比例尺
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void SettingScale()
        {
            cmbScale.SelectedIndexChanged -= new EventHandler(cmbScale_SelectedIndexChanged);
            cmbScale.SelectedItem = null;
            cmbScale.Text = Math.Round((m_Application as IFramework).MapControl.MapScale, 3).ToString();
            double cscale = 0;
            if ((m_Application as IFramework).IsMapCtrlactive)
            {
                cscale = (m_Application as IFramework).MapControl.MapScale;
            }
            else
            {
                cscale = (m_Application as IFramework).PageLayoutControl.ActiveView.FocusMap.MapScale;
            }
            long scale = cscale >= long.MaxValue ? long.MaxValue : (long)cscale;
            FrmScaleSetting frm = new FrmScaleSetting();
            frm.CurrentScale = "1:" + scale;
            frm.IsLock = _IsLock;
            frm.Activate();
            if (frm.ShowDialog() == DialogResult.OK)
            {
                _IsLock = frm.IsLock;
                SetScale(frm.Values);
            }
            //Application.DoEvents();
            //cmbScale.SelectedItem = null;
            //cmbScale.Text = Math.Round((m_Application as IFramework).MapControl.MapScale, 3).ToString();
            //Application.DoEvents();
            cmbScale.SelectedIndexChanged += new EventHandler(cmbScale_SelectedIndexChanged);
            //(m_Application as IFramework).MapControl.Refresh();
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="scales"></param>
        private void SetScale(List<string> scales)
        {
            cmbScale.Items.Clear();
            foreach (string s in scales)
            {
                cmbScale.Items.Add(s);
            }
            Button btn = new Button()
            {
                Text = "自定义比例尺" ,               
                ForeColor = Color.Black
            };            
            cmbScale.Items.Add(btn);            
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void timer_Tick(object sender, EventArgs e)
        {
            cmbScale.Text = Math.Round((m_Application as IFramework).MapControl.MapScale, 3).ToString();
            timer.Stop();
            timer.Enabled = false;
        }
    }
    
}
